import { DataSegment, SegmentItem } from "./DataSegment";
export class DataProcessor {
    public static buildString(dataSegment: DataSegment): string {
        let mainStringBuilder = "";
        for (let [key, value] of dataSegment.map) {
            let stringBuilder = "";
            stringBuilder += key;
            stringBuilder += "=";
            if (typeof value == "string") {
                stringBuilder += doEscape(value);
            } else if (value instanceof DataSegment) {
                stringBuilder += DataProcessor.buildString(value);
            } else if (value instanceof Array) {
                stringBuilder += "[";
                for (let i in value) {
                    stringBuilder += doEscape(i) + ",";
                }
                stringBuilder += "]";
            } else {
                throw "未知错误";
            }
            mainStringBuilder += stringBuilder + "&";
        }
        return "{" + mainStringBuilder + "}";
    }
    public static buildSegment(str: string) {
        let dataSegment = new DataSegment();
        let arrayList = split(str);
        let end = this.readSegment(arrayList, 0, dataSegment);
        return dataSegment;
    }
    public static readSegment(strings: Array<string>, start: number, dataSegment: DataSegment) {
        start += 1;
        while (strings[start] !== "}") {
            let key = strings[start];
            if (key == undefined)
                throw "index out of range";
            start += 1;
            start += 1;
            switch (strings[start]) {
                case "{":
                    let subSegment = new DataSegment();
                    start = this.readSegment(strings, start, subSegment);
                    dataSegment.put(key, subSegment);
                    break;
                case "[":
                    let arrayList = new Array<string>();
                    start = this.readArray(strings, start, arrayList);
                    dataSegment.put(key, arrayList);
                    break;
                default:
                    dataSegment.put(key, strings[start]);
                    start += 1;
                    break;
            }
            start += 1;
        }
        start += 1;
        return start;
    }
    public static readArray(strings: Array<string>, start: number, arrayList: Array<string>) {
        start += 1;
        while (strings[start] !== "]") {
            arrayList.push(strings[start]);
            start += 1;
            start += 1;
        }
        start += 1;
        return start;
    }

}
function split(str: string): Array<string> {
    let ans = new Array();
    let stringBulider = "";
    let escape = false;
    for (let i = 0; i < str.length; i++) {
        let ch = str[i];
        switch (ch) {
            case '\\':
                if (escape == true) {
                    stringBulider += ch;
                    escape = false;
                    break;
                }
                escape = true;
                break;
            case '{':
            case '}':
            case ']':
            case '[':
            case '=':
            case '&':
            case ',':
                if (escape == true) {
                    stringBulider += ch;
                    escape = false;
                } else {
                    let tmp = stringBulider;
                    if (tmp !== "") {
                        ans.push(tmp);
                        stringBulider = "";
                    }
                    ans.push(ch);
                }
                break;
            default:
                stringBulider += ch;
                break;
        }
    }
    return ans;
}

function doEscape(message: string): string {
    let ans = "";
    for (let i = 0; i < message.length; i++) {
        switch (message[i]) {
            case '{':
            case '}':
            case '[':
            case ']':
            case ',':
            case '\\':
            case '&':
            case '=':
                ans += "\\";
            default:
                ans += message[i];
        }
    }
    return ans;
}